package cvo.pro4.chess.client;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import cvo.pro4.chess.client.dto.BoardDto;
import cvo.pro4.chess.client.dto.PieceDto;
import cvo.pro4.chess.client.entities.BoardCoordinates;
import cvo.pro4.chess.client.entities.Color;
import cvo.pro4.chess.client.entities.Game;
import cvo.pro4.chess.client.entities.Piece;
import cvo.pro4.chess.client.entities.Player;
import cvo.pro4.chess.client.entities.Tile;
import cvo.pro4.chess.client.exceptions.IllegalCoordinatesException;

public class GameFacade {
	//singelton class
	
	//static instance van GameFacade
	private static GameFacade UniqueGameFacade; 
	
	
	/**
	 * Constructor is made private because of singleton access
	 */
	private GameFacade(){
		
	}
		
	/**
	 * Singleton for getting the GameFacade
	 * @return
	 */
	public static GameFacade getGameFacade() {
		//checken of GameFacade al is aangemaakt
		if (UniqueGameFacade == null){
			//GameFacade aanmaken omdat het nog niet is aangemaakt.
			UniqueGameFacade = new GameFacade();
		}
		//GameFace teruggeven
		return UniqueGameFacade;
	}
	
	
	
	//TODO: mode method on piece en give consistent parameters
	//movePiece om een stuk te verzetten van een plaats, naar een plaats
	public String movePiece(String startLocation, String destination) throws IllegalCoordinatesException{
		this.getPiece(startLocation).move(BoardCoordinates.create(destination));
		return null; //this.getPiece(destination).toString();
	}

	/**
	 * Strart a game with the given playe
	 * @param player
	 * @return The game which starte
	 * @throws IllegalCoordinatesException 
	 */
	public Game startGame(Player player) throws IllegalCoordinatesException{
		return Game.startNewGame(player);
	}
	
	
	/**
	 * Gets a game if there is one created
	 * @return The game if there is one
	 * @throws IllegalCoordinatesException
	 */
	public Game getGame() throws IllegalCoordinatesException{
		return Game.getGame();
	}
	
	public BoardDto getBoard() throws IllegalCoordinatesException{
		BoardDto boardDto = new BoardDto();
		
		List <PieceDto> pieces = new ArrayList<PieceDto>();
		List <String> tiles = new ArrayList<String>();
		
		for(Map.Entry<Tile, Piece> entry: getGame().getBoard().getMapping().entrySet()){
			StringBuilder tileString = new StringBuilder();
			Tile tile = entry.getKey();
			BoardCoordinates coordinates = tile.getCoordinates();
			tileString.append(coordinates.getX() + ";");
			tileString.append(coordinates.getY() + ";");
			if(tile.getColor().equals(Color.BLACK)){
				tileString.append("B");
			} else {
				tileString.append("W");
			}
			tiles.add(tileString.toString());
			
			Piece piece = entry.getValue();
			if(piece!=null){
				PieceDto pieceDto = new PieceDto();
				pieceDto.setColor(piece.getColor().toString());
				pieceDto.setId(piece.getId().toString());
				try {
					pieceDto.setPosition(piece.getCurrentPosition().getX() + ";" + piece.getCurrentPosition().getY());
				} catch (IllegalCoordinatesException e) {
					e.printStackTrace();
				}
				pieceDto.setType(piece.getName());
				pieces.add(pieceDto);
			}
		}
		boardDto.setPieces(pieces);
		boardDto.setTiles(tiles);
		return boardDto;
		
	}
	
	
	/**
	 * Joins a player to the game
	 * @param player
	 * @return The game handle
	 */
	public Game joinGame(Player player){
		return Game.joinGame(player);
	}
	
	/**
	 * Gets a piec at location
	 * @param location
	 * @return
	 * @throws IllegalCoordinatesException
	 */
	public Piece getPiece(String location) throws IllegalCoordinatesException{
		return Game.getGame().getBoard().getPieceAtLocation(BoardCoordinates.create(location));
	}
	
	
	/**
	 * Get the Tile at the correct location
	 * @param location The location of the Tile
	 * @return The correct Tile
	 * @throws IllegalCoordinatesException 
	 */
	public Tile getTileAt(String location) throws IllegalCoordinatesException{
		return Game.getGame().getBoard().getTileAt(BoardCoordinates.create(location));
	}
	


	/**
	 * Get the location of a piece
	 * @param piece The piece which loation whome we are trying to find
	 * @return The coordinates of the piece
	 * @throws IllegalCoordinatesException 
	 */
	public BoardCoordinates getLocation(Piece piece) throws IllegalCoordinatesException{
		return  Game.getGame().getBoard().getLocationOfPiece(piece);
	}
	
	
	/**
	 * Gets the possible moves of a piece at the given coordinates
	 * @param coordinates
	 * @return
	 * @throws IllegalCoordinatesException 
	 */
	public List<BoardCoordinates> getPossibleMove(String coordinates) throws IllegalCoordinatesException{
		Piece piece = Game.getGame().getBoard().getPieceAtLocation(BoardCoordinates.create(coordinates));
		return piece.getPossibleMoves();
	}
	
	
	
	/**
	 * Gets the tile where the piece is providing the piece is active 
	 * @param piece
	 * @return
	 * @throws IllegalCoordinatesException
	 */
	public Tile getTile(Piece piece) throws IllegalCoordinatesException{
		if(piece.isActive()){
			return  Game.getGame().getBoard().getTile(piece);
		}
		return null;
	}
	
}
